package services

import (
	"fiber-layout/app"
	"fiber-layout/app/constant"
	"fiber-layout/app/exceptions"
	"fiber-layout/app/requests"
	model "fiber-layout/databases/models"
	"fiber-layout/provider/config"
	"fiber-layout/provider/database"
	"fiber-layout/provider/logger"
	"github.com/gofiber/fiber/v2"
	"github.com/golang-jwt/jwt/v4"
	"time"
)

// RegisterService 用户注册
func RegisterService(request *requests.RegisterRequest, c *fiber.Ctx) error {
	// 验证用户名重复
	if _, ok := GetUserByField("username", request.Username); ok {
		return exceptions.Response(c, nil, constant.ErrUsernameExist.Error(), 4000)
	}
	//验证邮箱重复
	if _, ok := GetUserByField("email", request.Email); ok {
		return exceptions.Response(c, nil, constant.ErrEmailExist.Error(), 4000)
	}

	//生成盐值
	salt := app.RandString(6)
	u := &model.User{
		Username:   request.Username,
		Password:   app.NewPasswordByMd5(request.Password + salt),
		Email:      request.Email,
		Salt:       salt,
		RegisterIp: c.IP(),
	}

	// 失败 记录日志 并放回
	if err := database.DB.Model(&model.User{}).Save(&u).Error; err != nil {
		logger.Log.Error(constant.ErrCreateUser.Error() + err.Error())
		return exceptions.Error(c, constant.ErrCreateUser.Error())
	}
	return exceptions.Success(c, "success")
}

// LoginService 用户登录
func LoginService(r *requests.LoginRequest, c *fiber.Ctx) error {
	// 验证是否存在
	u := &model.User{}
	if err := database.DB.Model(&u).Where("username = ?", r.Account).Or(
		"email = ?", r.Account,
	).First(&u).Error; err != nil {
		return exceptions.Response(c, nil, constant.ErrLogin.Error(), 4000)
	}

	//验证密码
	if u.Password != app.NewPasswordByMd5(r.Password+u.Salt) {
		return exceptions.Response(c, nil, constant.ErrLogin.Error(), 4000)
	}
	//发放令牌
	claims := jwt.MapClaims{
		"username": u.Username,
		"id":       u.ID,
		"email":    u.Email,
		"exp":      time.Now().Add(time.Second * time.Duration(config.Config.GetInt("jwt.expires"))).Unix(),
	}
	// Create token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	t, err := token.SignedString([]byte(config.Config.GetString("jwt.secret")))
	if err != nil {
		logger.Log.Error(constant.ErrGenerateToken.Error() + err.Error())
		return exceptions.Error(c, constant.ErrGenerateToken.Error())
	}
	return exceptions.Response(c, fiber.Map{"token": t}, "success", 2000)
}

// DeleteService 删除用户
func DeleteService(id uint, c *fiber.Ctx) error {
	u := &model.User{}
	if err := database.DB.Model(&model.User{}).Where("id = ?", id).First(&u).Error; err != nil {
		return exceptions.Error(c, constant.ErrUserNotFound.Error())
	}
	if err := database.DB.Delete(&u).Error; err != nil {
		return exceptions.Error(c, constant.ErrDeleteUser.Error())
	}
	return exceptions.Success(c, "success")
}


// GetUserByField 根据字段获取用户
func GetUserByField(field string, value interface{}) (*model.User, bool) {
	u := &model.User{}
	if err := database.DB.Model(&model.User{}).Where(field+" = ?", value).First(&u).Error; err != nil {
		return nil, false
	}
	return u, true
}
